package com.apeli.common.utils.file;

import com.aliyun.oss.OSS;
import com.aliyun.oss.model.OSSObject;
import com.apeli.common.utils.StringUtils;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.util.UriUtils;

import javax.servlet.http.HttpServletResponse;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Date;
import java.util.UUID;

/**
 * @author liming
 */
@SuppressWarnings("all")
@Component
@Slf4j
@AllArgsConstructor(onConstructor = @__(@Autowired))
public class AliyunOssUtils {
    public static String BUCKET_NAME = "liming-bucket-apeli";

    private final OSS aliyunOssClient;

    public String uploadFile(InputStream inputStream, String filePath, String fileName) {
        try {
            if (inputStream != null && StringUtils.isNotBlank(filePath)) {
                String fullFilePath = filePath + UUID.randomUUID().toString() + fileName;
                log.info(">>>>>>>>>>AliyunOssUtil【uploadFile】>>>>>>>>>>上传文件到阿里云OSS服务开始,文件路径：{}", fullFilePath);
                aliyunOssClient.putObject(BUCKET_NAME, fullFilePath, inputStream);
                log.info(">>>>>>>>>>AliyunOssUtil【uploadFile】>>>>>>>>>>上传文件到阿里云OSS服务成功,文件路径：{}", fullFilePath);
                return fullFilePath;
            }
        } catch (Exception e) {
            log.error(">>>>>>>>>>AliyunOssUtil【uploadFile】>>>>>>>>>>上传文件到阿里云OSS服务失败,文件路径：{}", filePath, e);
        }
        return null;
    }

    /**
     * @param file
     * @return
     * @throws IOException
     */
    public String uploadFile(MultipartFile file) throws IOException {
        return uploadFile(file.getInputStream(), "data/person/img", file.getOriginalFilename());
    }

    /**
     * @param file
     * @return
     * @throws IOException
     */
    public String uploadFile(MultipartFile file,String fileName) throws IOException {
        return uploadFile(file.getInputStream(), "data/person/img/", fileName);
    }

    /**
     * 生成带临时签名的下载URL
     *
     * @param filePath 文件全路径
     * @return 文件下载url
     */
    public String generatePresignedUrl(String filePath) {
        return generatePresignedUrl(filePath, 24 * 3600 * 100L);
    }

    /**
     * 生成带临时签名的下载URL
     *
     * @param filePath   文件全路径
     * @param expiration 生效时间
     * @return 文件下载url
     */
    public String generatePresignedUrl(String filePath, long expiration) {
        Date date = new Date(System.currentTimeMillis() + expiration);
        // 生成以GET方法访问的签名URL，访客可以直接通过浏览器访问相关内容
        URL url = aliyunOssClient.generatePresignedUrl(BUCKET_NAME, filePath, date);
        return url.toString();
    }


    /**
     * 文件下载
     *
     * @param response    响应
     * @param filePath    文件路径
     * @param fileName    文件名
     * @param restoreFlag 恢复原始的文件名标识
     * @throws IOException 异常
     */
    public void downloadFile(HttpServletResponse response, String filePath, String fileName) throws IOException {
        response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
        response.setHeader("Content-Disposition", "attachment; filename=" + UriUtils.encode(fileName, "utf-8"));
        OSSObject ossObject = aliyunOssClient.getObject(BUCKET_NAME, filePath);
        // 读取文件内容
        BufferedInputStream in = new BufferedInputStream(ossObject.getObjectContent());
        BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
        byte[] buffer = new byte[1024];
        int length;
        try {
            while ((length = in.read(buffer)) != -1) {
                out.write(buffer, 0, length);
            }
        } catch (Exception e) {
            log.error(">>>>>>>>>>AliyunOssUtil【downloadFile】>>>>>>>>>>下载阿里云oss中的文件发生异常,文件路径：{}", filePath, e);
        } finally {
            try {
                in.close();
            } catch (IOException e) {
                log.error(">>>>>>>>>>AliyunOssUtil【downloadFile】>>>>>>>>>>输入流关闭异常", e);
            }
            try {
                out.flush();
                out.close();
            } catch (IOException e) {
                log.error(">>>>>>>>>>AliyunOssUtil【downloadFile】>>>>>>>>>>输出流关闭异常", e);
            }
        }
    }
}
